package com.naja.auth2clientfirst.support;

import org.springframework.boot.autoconfigure.security.oauth2.client.OAuth2ClientProperties;
import org.springframework.boot.autoconfigure.security.oauth2.client.OAuth2ClientPropertiesRegistrationAdapter;
import org.springframework.security.oauth2.client.registration.ClientRegistration;
import org.springframework.security.oauth2.client.registration.ClientRegistrationRepository;
import org.springframework.util.Assert;

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @auther wangjianying
 * @date 2023/12/21 14:46
 */
public class LazyInMemoryClientRegistrationRepository implements ClientRegistrationRepository, Iterable<ClientRegistration> {

    private final OAuth2ClientProperties properties;
    private Map<String, ClientRegistration> registrations;


    private static Map<String, ClientRegistration> createRegistrationsMap(List<ClientRegistration> registrations) {
        Assert.notEmpty(registrations, "未正确配置auth2客户端");
        return toUnmodifiableConcurrentMap(registrations);
    }

    private static Map<String, ClientRegistration> toUnmodifiableConcurrentMap(List<ClientRegistration> registrations) {
        ConcurrentHashMap<String, ClientRegistration> result = new ConcurrentHashMap<>();
        for (ClientRegistration registration : registrations) {
            result.put(registration.getRegistrationId(), registration);
        }
        return Collections.unmodifiableMap(result);
    }

    public LazyInMemoryClientRegistrationRepository(OAuth2ClientProperties properties) {
        this.properties = properties;

    }

    private void init() {
        if (this.registrations == null) {
            synchronized (this) {
                if (this.registrations == null) {
                    List<ClientRegistration> registrations = new ArrayList<>(
                            OAuth2ClientPropertiesRegistrationAdapter.getClientRegistrations(properties).values());
                    this.registrations = createRegistrationsMap(registrations);
                }
            }
        }

    }
    @Override
    public ClientRegistration findByRegistrationId(String registrationId) {
        init();
        Assert.hasText(registrationId, "registrationId cannot be empty");
        return this.registrations.get(registrationId);
    }

    /**
     * Returns an {@code Iterator} of {@link ClientRegistration}.
     * @return an {@code Iterator<ClientRegistration>}
     */
    @Override
    public Iterator<ClientRegistration> iterator() {
        init();
        return this.registrations.values().iterator();
    }

}
